package org.kjtc.weChatUtil;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import org.apache.log4j.Logger;
import org.kjtc.service.WxUserService;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * @author xiaojinlu
 * @create
 * @desc json转换工具类
 **/
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static Logger logger = Logger.getLogger(WxUserService.class);
    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param beanType 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 将数组结果集转化为json字符串
     *
     * @param arrStr  数组数据
     * @return
     */
    public static String arrayToStr(String[] arrStr) {
        String jsonStr = null;
        try {
            JSONArray jsonObject = JSONArray.fromObject(arrStr);
            jsonStr = jsonObject.toString();
        } catch (Exception e) {
            System.out.println("数组转json失败");
        }
        return jsonStr;
    }
    /**
     * 将json结果集转化为数组字符串
     *
     * @param arrStr  数组数据
     * @return
     */
    public static String[] strToArray(String arrStr) {
        String jsonStr = null;
        String[] arr =null;
        try {
            JSONArray jsonObject = JSONArray.fromObject(arrStr);
            arr =new String[jsonObject.size()];
            for (int i = 0; i < jsonObject.size(); i++) {
                Object o =  jsonObject.get(i);
                arr[i] = o.toString();
            }
        } catch (Exception e) {
            System.out.println("数组转json失败");
        }
        return arr;
    }

    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * json转map
     * @param jsonStr
     * @return
     */

    public static Map<String, Object> parseJsonToMap(String jsonStr){
        Map<String, Object> map = new HashMap<String, Object>();
        //最外层解析
        JSONObject json = JSONObject.fromObject(jsonStr);
        for(Object k : json.keySet()){
            Object v = json.get(k);
            //如果内层还是数组的话，继续解析
            if(v instanceof JSONArray){
                List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
                Iterator<JSONObject> it = ((JSONArray)v).iterator();
                while(it.hasNext()){
                    JSONObject json2 = it.next();
                    list.add(parseJsonToMap(json2.toString()));
                }
                map.put(k.toString(), list);
            } else {
                map.put(k.toString(), v);
            }
        }
        return map;
    }
    /**
     * map转json
     * @param map
     * @return
     */
    public static String mapToJson(Map<String, Object> map) {

        JSONObject jsonObject = JSONObject.fromObject(map);
        //3、将json对象转化为json字符串
        return jsonObject.toString();
       /* Set<String> keys = map.keySet();
        String key = "";
        String value = "";
        StringBuffer jsonBuffer = new StringBuffer();
        jsonBuffer.append("{");
        for (Iterator<String> it = keys.iterator(); it.hasNext();) {
            key = (String) it.next();
            value = (String) map.get(key);
            jsonBuffer.append(key + ":" +"\""+ value+"\"");
            if (it.hasNext()) {
                jsonBuffer.append(",");
            }
        }
        jsonBuffer.append("}");*/
      //  return jsonBuffer.toString();
    }

    /**
     * 将对象转换为json格式字符串
     *
     * @param obj
     * @return json string
     */
    public static String toJSON(Object obj) {
        ObjectMapper om = new ObjectMapper();
        try {
            String json = om.writeValueAsString(obj);
            return json;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *
     * 将json形式字符串转换为java实体类
     *
     */
    public static <T> T parse(String jsonStr, Class<T> clazz) {
        ObjectMapper om = new ObjectMapper();
        T readValue = null;
        try {
            readValue = om.readValue(jsonStr, clazz);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return readValue;
    }

    /**
     * 数组转换为JSON
     *
     * @param array
     * @return
     */
    public static String javaArray2Json(Object[] array) {
        JSONArray jsonarray = JSONArray.fromObject(array);
        return jsonarray.toString();
    }

    /**
     * Json数组转化为Java数组
     *
     * @param jsonArray
     * @param clas
     * @return
     */
    public static Object jsonArray2JavaArrray(String jsonArray, Class clas) {
        JsonConfig jconfig = new JsonConfig();
        jconfig.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
        jconfig.setRootClass(clas);
        JSONArray jarr = JSONArray.fromObject(jsonArray);
        return JSONSerializer.toJava(jarr, jconfig);
    }


        /**
       * 实体类转map
       * @param obj
       * @return
       */
              public static Map<String, Object> convertBeanToMap(Object obj) {
    if (obj == null) {
      return null;
    }
    Map<String, Object> map = new HashMap<String, Object>();
    try {
      BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
      PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
      for (PropertyDescriptor property : propertyDescriptors) {
        String key = property.getName();
        // 过滤class属性
        if (!key.equals("class")) {
          // 得到property对应的getter方法
          Method getter = property.getReadMethod();
          Object value = getter.invoke(obj);
          if(null==value){
            map.put(key,"");
          }else{
            map.put(key,value);
          }
        }




      }
    } catch (Exception e) {
      logger.error("convertBean2Map Error {}" ,e);
    }
    return map;
  }




  /**
   * map 转实体类
   * @param clazz
   * @param map
   * @param <T>
   * @return
   */
          public static <T> T convertMapToBean(Class<T> clazz, Map<String,Object> map) {
    T obj = null;
    try {
      BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
      obj = clazz.newInstance(); // 创建 JavaBean 对象




      // 给 JavaBean 对象的属性赋值
      PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
      for (int i = 0; i < propertyDescriptors.length; i++) {
        PropertyDescriptor descriptor = propertyDescriptors[i];
        String propertyName = descriptor.getName();
        if (map.containsKey(propertyName)) {
          // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
          Object value = map.get(propertyName);
          if ("".equals(value)) {
            value = null;
          }
          Object[] args = new Object[1];
          args[0] = value;
          descriptor.getWriteMethod().invoke(obj, args);




        }
      }
    } catch (IllegalAccessException e) {
      logger.error("convertMapToBean 实例化JavaBean失败 Error{}" ,e);
    } catch (IntrospectionException e) {
      logger.error("convertMapToBean 分析类属性失败 Error{}" ,e);
    } catch (IllegalArgumentException e) {
      logger.error("convertMapToBean 映射错误 Error{}" ,e);
    } catch (InstantiationException e) {
      logger.error("convertMapToBean 实例化 JavaBean 失败 Error{}" ,e);
    }catch (InvocationTargetException e){
      logger.error("convertMapToBean字段映射失败 Error{}" ,e);
    }catch (Exception e){
      logger.error("convertMapToBean Error{}" ,e);
    }
    return (T) obj;
  }
  //将map通过反射转化为实体
          public static  Object MapToModel(Map<String,Object> map,Object o) throws Exception{
    if (!map.isEmpty()) {
      for (String k : map.keySet()) {
        Object v =null;
        if (!k.isEmpty()) {
          v = map.get(k);
        }
        Field[] fields = null;
        fields = o.getClass().getDeclaredFields();
        String clzName = o.getClass().getSimpleName();
        for (Field field : fields) {
          int mod = field.getModifiers();


          if (field.getName().toUpperCase().equals(k.toUpperCase())) {
            field.setAccessible(true);


            //region--进行类型判断
             String type=field.getType().toString();
             if (type.endsWith("String")){
               if (v!=null){
                 v=v.toString();
               }else {
                 v="";
               }
             }
            if (type.endsWith("Date")){
              v=new Date(v.toString());
            }
            if (type.endsWith("Boolean")){


             v=Boolean.getBoolean(v.toString());
            }
            if (type.endsWith("int")){


              v=new Integer(v.toString());
            }
            if (type.endsWith("Long")){


              v=new Long(v.toString());
            }






            //endregion
            field.set(o, v);


          }


        }


      }
    }
    return o;
  }
  /**
   * 实体对象转成Map
   * @param obj 实体对象
   * @return
   */
          public static Map<String, Object> object2Map(Object obj) {
    Map<String, Object> map = new HashMap<>();
    if (obj == null) {
      return map;
    }
    Class clazz = obj.getClass();
    Field[] fields = clazz.getDeclaredFields();
    try {
      for (Field field : fields) {
        field.setAccessible(true);
        map.put(field.getName(), field.get(obj));
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return map;
  }
  /**
   * Map转成实体对象
   * @param map map实体对象包含属性
   * @param clazz 实体对象类型
   * @return
   */
          public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
    if (map == null) {
      return null;
    }
    Object obj = null;
    try {
      obj = clazz.newInstance();




      Field[] fields = obj.getClass().getDeclaredFields();
      for (Field field : fields) {
        int mod = field.getModifiers();
        if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
          continue;
        }
        field.setAccessible(true);
        field.set(obj, map.get(field.getName()));
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return obj;
  } 
}
